<!--
 * 对话历史组件
 * 功能：显示用户和AI的对话记录，支持消息操作（复制、删除、重新生成）
 * 作者：MetasoCreator Team
 * 创建时间：2025-01-19
 * 修改时间：2025-01-19
-->

<template>
  <div class="chat-history" ref="chatHistoryRef">
    <div class="messages-container">
      <!-- 消息列表 -->
      <div
        v-for="(message, index) in displayMessages"
        :key="message.id || index"
        :class="[
          'message-item',
          `message-${message.type}`,
          { 'welcome-message': message.welcome },
          { 'error-message': message.error }
        ]"
      >
        <!-- 用户消息 -->
        <div v-if="message.type === 'user'" class="user-message">
          <div class="message-content">
            <div class="message-text">{{ message.content }}</div>
            <div class="message-meta">
              <el-tag size="small" :type="getModeTagType(message.mode)">
                {{ getModeLabel(message.mode) }}
              </el-tag>
              <span class="message-time">{{ formatTime(message.timestamp) }}</span>
            </div>
          </div>
          <div class="message-avatar">
            <el-avatar :size="32" :src="userAvatar">
              <el-icon><User /></el-icon>
            </el-avatar>
          </div>
        </div>

        <!-- AI消息 -->
        <div v-else class="ai-message">
          <div class="message-avatar">
            <el-avatar :size="32" class="ai-avatar">
              <el-icon><ChatDotRound /></el-icon>
            </el-avatar>
          </div>
          <div class="message-content">
            <div class="message-text" v-html="formatMessageContent(message.content)"></div>

            <div class="message-meta">
              <span class="message-time">{{ formatTime(message.timestamp) }}</span>
              <div class="message-actions">
                <el-button
                  size="small"
                  text
                  @click="handleCopy(message.content)"
                  title="复制内容"
                >
                  <el-icon><DocumentCopy /></el-icon>
                </el-button>
                <el-button
                  v-if="!message.welcome"
                  size="small"
                  text
                  @click="handleRegenerate(message.id)"
                  title="重新生成"
                >
                  <el-icon><Refresh /></el-icon>
                </el-button>
                <el-button
                  v-if="!message.welcome"
                  size="small"
                  text
                  type="danger"
                  @click="handleDelete(message.id)"
                  title="删除消息"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 加载状态 -->
      <div v-if="props.loading" class="message-item assistant-message loading-message">
        <div class="message-avatar">
          <el-icon class="avatar-icon">
            <Loading />
          </el-icon>
        </div>
        <div class="message-content">
          <div class="message-bubble">
            <div class="loading-dots">
              <span></span>
              <span></span>
              <span></span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 滚动到底部按钮 -->
    <el-button
      v-show="showScrollButton"
      class="scroll-to-bottom"
      circle
      type="primary"
      @click="scrollToBottom"
    >
      <el-icon><ArrowDown /></el-icon>
    </el-button>
  </div>
</template>

<script setup>
import { computed, ref, nextTick, watch, onMounted, onUnmounted } from 'vue'
import {
  User,
  ChatDotRound,
  DocumentCopy,
  Refresh,
  Delete,
  ArrowDown,
  Loading
} from '@element-plus/icons-vue'

// Props
const props = defineProps({
  messages: {
    type: Array,
    default: () => []
  },
  loading: {
    type: Boolean,
    default: false
  }
})

// Emits
const emit = defineEmits(['copy', 'regenerate', 'delete'])

// 响应式数据
const chatHistoryRef = ref(null)
const showScrollButton = ref(false)
const userAvatar = ref('') // 可以设置用户头像URL

// 计算属性
const displayMessages = computed(() => {
  return props.messages || []
})

// 方法
const formatTime = (timestamp) => {
  const date = new Date(timestamp)
  const now = new Date()
  const diff = now - date
  
  if (diff < 60000) { // 1分钟内
    return '刚刚'
  } else if (diff < 3600000) { // 1小时内
    return `${Math.floor(diff / 60000)}分钟前`
  } else if (diff < 86400000) { // 24小时内
    return `${Math.floor(diff / 3600000)}小时前`
  } else {
    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
  }
}

const formatMessageContent = (content) => {
  // 简单的Markdown格式化
  return content
    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
    .replace(/\*(.*?)\*/g, '<em>$1</em>')
    .replace(/`(.*?)`/g, '<code>$1</code>')
    .replace(/\n/g, '<br>')
}

const getModeLabel = (mode) => {
  const labels = {
    web_search: '网页搜索',
    academic_search: '学术搜索',
    qa: '智能问答',
    content_creation: '内容创作',
    system: '系统'
  }
  return labels[mode] || '未知'
}

const getModeTagType = (mode) => {
  const types = {
    web_search: 'primary',
    academic_search: 'success',
    qa: 'warning',
    content_creation: 'danger',
    system: 'info'
  }
  return types[mode] || 'info'
}



const handleCopy = (content) => {
  emit('copy', content)
}

const handleRegenerate = (messageId) => {
  emit('regenerate', messageId)
}

const handleDelete = (messageId) => {
  emit('delete', messageId)
}

const scrollToBottom = () => {
  if (chatHistoryRef.value) {
    const container = chatHistoryRef.value
    container.scrollTop = container.scrollHeight
  }
}

const checkScrollPosition = () => {
  if (chatHistoryRef.value) {
    const container = chatHistoryRef.value
    const isNearBottom = container.scrollHeight - container.scrollTop - container.clientHeight < 100
    showScrollButton.value = !isNearBottom
  }
}

// 监听消息变化，自动滚动到底部
watch(
  () => props.messages.length,
  async () => {
    await nextTick()
    if (!showScrollButton.value) {
      scrollToBottom()
    }
  }
)

// 监听加载状态变化
watch(
  () => props.loading,
  async () => {
    await nextTick()
    if (!showScrollButton.value) {
      scrollToBottom()
    }
  }
)

// 生命周期
onMounted(() => {
  if (chatHistoryRef.value) {
    chatHistoryRef.value.addEventListener('scroll', checkScrollPosition)
  }
  scrollToBottom()
})

onUnmounted(() => {
  if (chatHistoryRef.value) {
    chatHistoryRef.value.removeEventListener('scroll', checkScrollPosition)
  }
})
</script>

<style scoped>
.chat-history {
  position: relative;
  height: 100%;
  overflow-y: auto;
  padding: 10px 0;
}

.messages-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding-bottom: 20px;
}

.message-item {
  display: flex;
  width: 100%;
}

/* 用户消息样式 */
.user-message {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  width: 100%;
}

.user-message .message-content {
  max-width: 70%;
  background: var(--color-primary);
  color: white;
  padding: 12px 16px;
  border-radius: 18px 18px 4px 18px;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

/* AI消息样式 */
.ai-message {
  display: flex;
  justify-content: flex-start;
  gap: 12px;
  width: 100%;
}

.ai-message .message-content {
  max-width: 80%;
  background: var(--bg-secondary);
  color: var(--text-primary);
  padding: 12px 16px;
  border-radius: 18px 18px 18px 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.welcome-message .message-content {
  background: linear-gradient(135deg, var(--color-primary-light), var(--color-primary));
  color: white;
}

.error-message .message-content {
  background: var(--color-danger-light);
  border-left: 4px solid var(--color-danger);
}

.message-text {
  line-height: 1.6;
  word-wrap: break-word;
  margin-bottom: 8px;
}

.message-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 8px;
  font-size: 12px;
  opacity: 0.7;
}

.message-time {
  color: inherit;
}

.message-actions {
  display: flex;
  gap: 4px;
}

.message-avatar {
  flex-shrink: 0;
}

.ai-avatar {
  background: var(--color-primary);
  color: white;
}



/* 加载状态样式 */
.loading-message {
  display: flex;
  justify-content: flex-start;
  gap: 12px;
  width: 100%;
}

.loading-message .message-content {
  background: var(--bg-secondary);
  padding: 12px 16px;
  border-radius: 18px 18px 18px 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.typing-indicator {
  display: flex;
  gap: 4px;
  margin-bottom: 8px;
}

.typing-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-primary);
  animation: typing 1.4s infinite ease-in-out;
}

.typing-dot:nth-child(1) {
  animation-delay: -0.32s;
}

.typing-dot:nth-child(2) {
  animation-delay: -0.16s;
}

.loading-text {
  font-size: 13px;
  color: var(--text-secondary);
}

/* 滚动到底部按钮 */
.scroll-to-bottom {
  position: absolute;
  bottom: 20px;
  right: 20px;
  z-index: 10;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 动画 */
@keyframes typing {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .user-message .message-content,
  .ai-message .message-content {
    max-width: 85%;
  }
  
  .message-actions {
    flex-direction: column;
    gap: 2px;
  }
}

@media (max-width: 480px) {
  .user-message .message-content,
  .ai-message .message-content {
    max-width: 90%;
  }
  
  .messages-container {
    gap: 15px;
  }
  
  .scroll-to-bottom {
    bottom: 15px;
    right: 15px;
  }
}

/* 暗色主题适配 */
:root[data-theme="dark"] .ai-message .message-content {
  background: var(--bg-secondary);
  color: var(--text-primary);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}



:root[data-theme="dark"] .loading-message .message-content {
  background: var(--bg-secondary);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* 滚动条样式 */
.chat-history::-webkit-scrollbar {
  width: 6px;
}

.chat-history::-webkit-scrollbar-track {
  background: transparent;
}

.chat-history::-webkit-scrollbar-thumb {
  background: var(--border-color);
  border-radius: 3px;
}

.chat-history::-webkit-scrollbar-thumb:hover {
  background: var(--text-secondary);
}
</style>